﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace DevOnServer
{
    public class CFileReader
    {
        public bool load(string filename)
        {
            return load(filename, Encoding.Default);
        }

        public bool load(string filename, Encoding encoding)
        {
            string buffer = null;
            try
            {
                buffer = File.ReadAllText(filename, encoding);
            }
            catch (Exception e)
            {
                CConsole.WriteLine("Can't open file '{0}': {1}", filename, e.Message);
                return false;
            }

            int filelenght = buffer.Length;
            if (filelenght == 0)
                return true;

            int i = 0;
            char b;
            StringBuilder tok = new StringBuilder();
            bool isstring = false;
            while (i < filelenght)
            {
                b = (char)buffer[i];

                if (!isstring && b == '/' && tok.Length > 0 && tok[tok.Length - 1] == '/')
                {
                    tok.Remove(tok.Length - 1, 1);
                    while (buffer[i] != '\n' && i < filelenght)
                        i++;
                    i++;
                    continue;
                }

                if (!isstring && b == '*' && tok.Length > 0 && tok[tok.Length - 1] == '/')
                {
                    tok.Remove(tok.Length - 1, 1);
                    i++;
                    while (buffer[i] != '*' && buffer[i + 1] != '/' && i < filelenght)
                        i++;
                    i += 2;
                    continue;
                }

                if (b == '"')
                {
                    if (!isstring)
                        isstring = true;
                    else
                    {
                        m_tokens.Add(tok.ToString());
                        tok = new StringBuilder();
                        isstring = false;
                        i++;
                    }
                }

                if ((b == '\r' || b == '\n' || (!isstring && (b == ' ' || b == '\t'))))
                {
                    if (tok.Length > 0 || isstring)
                    {
                        m_tokens.Add(tok.ToString());
                        tok = new StringBuilder();
                        isstring = false;
                    }
                }
                else if (b != '"' && b != 65279)
                {
                    tok.Insert(tok.Length, b);
                }

                i++;
            }

            if (tok.Length > 0)
                m_tokens.Add(tok.ToString());

            return true;
        }

        public bool end
        {
            get
            {
                return m_position > m_tokens.Count;
            }
        }

        public void move(int v)
        {
            m_position += v;
        }

        public string getString()
        {
            m_position++;
            if (end)
                return "";
            else
                return m_tokens[m_position - 1];
        }

        public bool getBool()
        {
            string s = getString();
            if (s == "0" || s == "false")
                return false;
            else
                return true;
        }

        public int getInt()
        {
            int v;
            if (int.TryParse(getString(), out v))
                return v;
            else
                return -1;
        }

        public long getLong()
        {
            long v;
            if (long.TryParse(getString(), out v))
                return v;
            else
                return -1;
        }

        public float getFloat()
        {
            float v;
            if (float.TryParse(getString().Replace('f', ' '), out v))
                return v;
            else
                return -1f;
        }

        public ulong getULong() // on peut avoir des flags donc hexa
        {
            string s = getString();
            if (s.StartsWith("0x"))
            {
                s = s.Replace("0x", "");
                return ulong.Parse(s, System.Globalization.NumberStyles.HexNumber);
            }
            else
            {
                ulong v;
                if (ulong.TryParse(s, out v))
                    return v;
                else
                    return 0;
            }
        }

        private List<string> m_tokens = new List<string>();

        private int m_position = 0;
    }
}